package xyz.example.securegeyserext.util

import java.nio.ByteBuffer
import java.security.SecureRandom
import java.util.Base64
import javax.crypto.Cipher
import javax.crypto.SecretKey
import javax.crypto.spec.GCMParameterSpec
import javax.crypto.spec.SecretKeySpec

object AESCipher {
    private const val ALG = "AES/GCM/NoPadding"

    fun readKey(b64: String): SecretKey =
        SecretKeySpec(Base64.getDecoder().decode(b64), "AES")

    fun encrypt(key: SecretKey, plain: ByteArray): ByteArray {
        val iv = SecureRandom.getInstanceStrong().generateSeed(12)
        val cipher = Cipher.getInstance(ALG)
        cipher.init(Cipher.ENCRYPT_MODE, key, GCMParameterSpec(128, iv))
        val enc = cipher.doFinal(plain)
        return ByteBuffer.allocate(iv.size + enc.size).put(iv).put(enc).array()
    }

    fun decrypt(key: SecretKey, cipherBytes: ByteArray): ByteArray {
        val bb = ByteBuffer.wrap(cipherBytes)
        val iv = ByteArray(12)
        bb.get(iv)
        val enc = ByteArray(bb.remaining())
        bb.get(enc)
        val cipher = Cipher.getInstance(ALG)
        cipher.init(Cipher.DECRYPT_MODE, key, GCMParameterSpec(128, iv))
        return cipher.doFinal(enc)
    }
}
